﻿/*
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * See product pages for more information.
 * http://closesudoku.codeplex.com
 * Copyright (C), 2010, hrondra
 */
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace Close.Classes
{
    /// <summary>
    /// One second timer.
    /// </summary>
    class StopWatch
    {
        private Timer _timer;
        private double _offset;
        private DateTime _startTime;
        private DateTime _stopTime;
        private bool _timerRunning;

        /// <summary>
        /// Create new one second timer.
        /// </summary>
        /// <param name="offset">previous elapsed time</param>
        public StopWatch(double offset)
        {
            Constructor(offset, true);
        }

        /// <summary>
        /// Create new one second timer
        /// </summary>
        public StopWatch(double offset, bool running)
        {
            Constructor(offset, running);
        }

        private void Constructor(double offset, bool running)
        {
            _offset = offset;
            _startTime = DateTime.Now;
            _timer = new Timer();
            _timer.Interval = 1000; //every second
            _timer.Tick += new EventHandler(_timer_Tick);
            _timer.Enabled = running;
            _timerRunning = running;
        }

        /// <summary>
        /// Time elapsed.
        /// </summary>
        public double ElapsedTime
        {
            get 
            {
                DateTime endTime = _timerRunning ? DateTime.Now : _stopTime;
                TimeSpan elapsed = endTime - _startTime;
                if (!_timer.Enabled)
                {
                    return _offset;
                }
                if (elapsed.TotalSeconds > (double.MaxValue - _offset))
                    return double.MaxValue;
                else
                    return elapsed.TotalSeconds + _offset;
            }
        }

        /// <summary>
        /// Set to zero.
        /// </summary>
        public void Reset()
        {
            _startTime = DateTime.Now;
            _offset = 0;
            _timerRunning = true;
            _timer.Enabled = true;
        }


        /// <summary>
        /// Stop.
        /// </summary>
        public void Stop()
        {
            _timerRunning = false;
            _stopTime = DateTime.Now;
        }

        public delegate void TimeDelegate(double e);
        /// <summary>
        /// One second elapsed - return seconds from the begenning
        /// </summary>
        public event TimeDelegate OneSecondTick;
        /// <summary>
        /// One second elapsed.
        /// </summary>
        private void _timer_Tick(object sender, EventArgs e)
        {
            if (OneSecondTick != null)
                OneSecondTick(ElapsedTime);
        }        

    }
}
